home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / COMMS / C101.ZIP / UUPC11XS.ZIP / MAIL / MLIB.C < prev    next >
C/C++ Source or Header  |  1992-11-21  |  12KB  |  401 lines

  1. /*
  2.    ibmpc/mlib.c   by <skl@van-bc.UUCP>   August/87
  3.  
  4.  
  5.    Mailer UA system-dependent library
  6.  
  7.    Services to provide in mlib.c:
  8.  
  9.    Get a single character from the console.
  10.    Invoke the local editor on a given file.
  11.    Determine if a given file stream points to the console.
  12.    Get a line from the console.
  13.    Invoke a local pager on a given file.
  14.  
  15.    Update history:
  16.  
  17.    13 May 89      Use PC format path names for editor                   ahd
  18.    01 Oct 89      Make Console_fgets use far pointers
  19.                   Alter Console_fgets and Is_Console to type boolean
  20.                                                                         ahd
  21.    29 Jul 90      Use PC format path names for pager                    ahd
  22. */
  23.  
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <conio.h>
  28. #include <io.h>
  29. #include <dos.h>
  30.  
  31. #include "lib.h"
  32. #include "hlib.h"
  33.  
  34. #ifdef FAMILYAPI
  35. #define SIMPLE_CONSOLE_FGETS
  36. #endif
  37.  
  38. #ifdef _Windows
  39. #define SIMPLE_CONSOLE_FGETS
  40. #endif
  41.  
  42. #ifndef SIMPLE_CONSOLE_FGETS
  43. #define MULTIPLEX 0x2f        /* 8086 DOS Interrupt for multiplexing */
  44.  
  45. static int DOSRead( char *buff, const int buflen);
  46.  
  47. static boolean DOSKeyActive( void );
  48.  
  49. static int DOSKeyRead( char *buff , int buflen );
  50.  
  51. #endif
  52.  
  53.  
  54. /*
  55.    G e t _ O n e
  56.  
  57.    Get a single character from the console
  58. */
  59.  
  60. int Get_One()
  61. {
  62.  
  63.    return getch();
  64.  
  65. } /*Get_One*/
  66.  
  67.  
  68. /*
  69.    I n v o k e _ E d i t o r
  70.  
  71.    Invoke the user's editor to edit a text file
  72. */
  73.  
  74. int Invoke_Editor(const char *ecmd, const char *filename)
  75. {
  76.    char command[FILENAME_MAX*2 + 1];
  77.    char tempname[FILENAME_MAX];                          /* ahd   */
  78.    int  column = 0;                                      /* ahd   */
  79.  
  80.    if (ecmd == nil(char)) {
  81.       printf("Invoke_Editor: No editor specified.\n");
  82.       return 1;
  83.    }
  84.  
  85.    puts("\nInvoking editor ...\n");
  86.  
  87.    strcpy(tempname,filename);                            /* ahd   */
  88.  
  89.    while (tempname[column] != '\0') {                    /* ahd   */
  90.       if (tempname[column] ==  '/')                      /* ahd   */
  91.          tempname[column] = '\\';                        /* ahd   */
  92.       column = column + 1;                               /* ahd   */
  93.   }                                                      /* ahd   */
  94.  
  95.  
  96.    sprintf(command, ecmd, tempname);                     /* ahd   */
  97.    if (system(command) != 0) {
  98.       printf("Invoke_Editor: system(\"%s\") failed.\n", command);
  99.       return 2;
  100.    }
  101.  
  102.    return 0;
  103.  
  104. } /*Invoke_Editor*/
  105.  
  106.  
  107. /*
  108.    Is_Console - is this stream from the console?
  109.  
  110.    Note: isatty actually returns if the stream is a character device,
  111.          thus causing device NUL to appear interactive; this is not
  112.          acceptable, but I don't know a trivial fix.           ahd
  113. */
  114.  
  115. boolean Is_Console(FILE *stream)                                  /* ahd   */
  116. {
  117.  
  118.    return isatty(fileno(stream));
  119.  
  120. } /*Is_Console*/
  121.  
  122.  
  123. /*
  124.    Console_fgets - get a line of input from the local console
  125.  
  126.    This is a hook to allow for using the local system's facility
  127.    for input line editing.  We call DOS to perform a line read,
  128.    thus allowing utilities like DOSEDIT or CED to do their fancy work.
  129. */
  130.  
  131. #ifndef SIMPLE_CONSOLE_FGETS
  132.  
  133. boolean Console_fgets(char *buff, int buflen, char *prompt)
  134. {
  135.    static boolean eof = FALSE;    /* pending EOF flag  */
  136.  
  137.    char *eofptr;
  138.  
  139.    if (eof) {           /* have a pending EOF?  */
  140.       eof = FALSE;      /* no more pending EOF  */
  141.       return FALSE;     /* signal the EOF    */
  142.    }
  143.  
  144. /*--------------------------------------------------------------------*/
  145. /*      Prompt the user, read the data, and then go to a new line     */
  146. /*--------------------------------------------------------------------*/
  147.  
  148.    fputs(prompt, stdout);
  149.  
  150.    if ( DOSKeyActive() )
  151.       buflen = DOSKeyRead( buff, buflen );
  152.    else
  153.       buflen = DOSRead( buff, buflen );
  154.     putchar('\n');
  155.  
  156. /*--------------------------------------------------------------------*/
  157. /*             Determine if we hit end of file on the read            */
  158. /*--------------------------------------------------------------------*/
  159.  
  160.    if ( buflen == -1 )
  161.    {
  162.       *buff = '\0';
  163.       return FALSE;
  164.    }
  165.  
  166. /*--------------------------------------------------------------------*/
  167. /*                        Terminate the buffer                        */
  168. /*--------------------------------------------------------------------*/
  169.  
  170.    buff[buflen] = '\n';
  171.    buff[buflen + 1] = '\0';
  172.  
  173.    if ((eofptr = strchr(buff, '\x1a')) == nil(char))
  174.       return TRUE;      /* an ordinary successful read   */
  175.    else if (eofptr == buff)
  176.    {
  177.       return FALSE;     /* signal EOF right away      */
  178.    }
  179.    else {
  180.       eof = TRUE;       /* we now have a pending EOF  */
  181.       *eofptr = '\0';
  182.       return TRUE;      /* read successful but EOF next  */
  183.    } /* else */
  184.  
  185. } /*Console_fgets*/
  186.  
  187. /*--------------------------------------------------------------------*/
  188. /*    D O S R e a d                                                   */
  189. /*                                                                    */
  190. /*    Read from console under DOS without DOSKEY                      */
  191. /*--------------------------------------------------------------------*/
  192.  
  193. static int DOSRead( char *buff, const int buflen)
  194. {
  195.    union REGS regs;
  196.    struct SREGS sregs;
  197.  
  198.    struct {
  199.       unsigned char maximum, actual;
  200.       char buffer[255];
  201.    } request;
  202.  
  203.    char far *p = (char far *) &request;
  204.  
  205. /*--------------------------------------------------------------------*/
  206. /*            Set up the address of our read buffer for DOS           */
  207. /*--------------------------------------------------------------------*/
  208.  
  209.    sregs.ds = FP_SEG( p );    /* Use segment of the buffer           */
  210.    regs.x.dx = (unsigned int)(&request);
  211.    request.maximum = (unsigned char) min( buflen - 1,
  212.                                           sizeof request.buffer);
  213.    regs.h.ah = 0x0a;          /* Buffered keyboard input             */
  214.  
  215. /*--------------------------------------------------------------------*/
  216. /*                  Invoke the buffered console read                  */
  217. /*--------------------------------------------------------------------*/
  218.  
  219.    intdosx(®s, ®s, &sregs);
  220.  
  221. /*--------------------------------------------------------------------*/
  222. /*                        Now return the result                       */
  223. /*--------------------------------------------------------------------*/
  224.  
  225.    memcpy( buff, request.buffer, request.actual );
  226.    return (unsigned int) request.actual;
  227.  
  228. } /* DOSRead */
  229.  
  230. /*--------------------------------------------------------------------*/
  231. /*    D O S K e y A c t i v e                                         */
  232. /*                                                                    */
  233. /*    Determine if the DOS Key command line editor is active          */
  234. /*--------------------------------------------------------------------*/
  235.  
  236. static boolean DOSKeyActive( void )
  237. {
  238.    static boolean first_pass = TRUE;
  239.    static boolean active = FALSE;
  240.  
  241.    if ( first_pass )
  242.    {
  243.       first_pass = FALSE;
  244.       if ((_osmajor > 4) )
  245.       {
  246.          union REGS regs;
  247.  
  248. #ifdef __TURBOC__
  249.          if ( getvect( MULTIPLEX ) == NULL )
  250. #else
  251.          if ( _dos_getvect( MULTIPLEX ) == NULL )
  252. #endif
  253.             printmsg(0,"Multiplex interrupt not installed???\n");
  254.          else {
  255.             regs.x.ax = 0x4800;     /* Request for DOS Key active */
  256.             int86( MULTIPLEX , ®s, ®s );
  257.             if ( regs.h.al != 0x00 )
  258.                active = TRUE;
  259.          }
  260.       } /* if (_osmajor > 4 ) */
  261.    } /* if ( first_pass ) */
  262.  
  263. /*--------------------------------------------------------------------*/
  264. /*                          Return to caller                          */
  265. /*--------------------------------------------------------------------*/
  266.  
  267.    if ( bflag[F_DOSKEY] && ! active )
  268.    {
  269.      printmsg(0,"DOSKEY support not enabled, option disabled");
  270.      bflag[F_DOSKEY] = FALSE;
  271.    }
  272.  
  273.    return bflag[F_DOSKEY] && active;
  274.  
  275. } /* DOSKeyActive */
  276.  
  277.  
  278. /*--------------------------------------------------------------------*/
  279. /*    D O S K e y R e a d                                             */
  280. /*                                                                    */
  281. /*    Read a line from the terminal using DOS Key                     */
  282. /*--------------------------------------------------------------------*/
  283.  
  284. static int DOSKeyRead( char *buff , int buflen )
  285. {
  286.    union REGS regs;
  287.    struct SREGS sregs;
  288.  
  289.    struct {
  290.       unsigned char maximum, actual;
  291.       char buffer[126];
  292.    } request;
  293.  
  294.    char far *p = (char far *) &request;
  295.  
  296. /*--------------------------------------------------------------------*/
  297. /*                   Set up for the DOSKEY read call                  */
  298. /*--------------------------------------------------------------------*/
  299.  
  300.    sregs.ds = FP_SEG( p );    /* Use segment of the buffer           */
  301.    regs.x.dx = (unsigned int)(&request);
  302.    regs.x.ax = 0x4810;
  303.    request.maximum = (unsigned char) min( buflen - 1, sizeof request );
  304.  
  305. /*--------------------------------------------------------------------*/
  306. /*                      Issue the call to DOSKEY                      */
  307. /*--------------------------------------------------------------------*/
  308.  
  309.    int86x( MULTIPLEX, ®s, ®s, &sregs );
  310.  
  311. /*--------------------------------------------------------------------*/
  312. /*                          Check the result                          */
  313. /*--------------------------------------------------------------------*/
  314.  
  315.    if ( regs.x.ax == 0 )      /* Function succeed?                */
  316.    {
  317.       buflen = request.actual;
  318.       memcpy( buff, request.buffer , buflen );
  319.    } /* if ( regs.x.ax == 0 ) */
  320.    else {                        /* Function failed, report it    */
  321.       printmsg(0,"DOSKEY read failed!");
  322.       buflen = -1;
  323.    } /* else */
  324.  
  325. /*--------------------------------------------------------------------*/
  326. /*                          Return to caller                          */
  327. /*--------------------------------------------------------------------*/
  328.  
  329.    return buflen;
  330.  
  331. } /* DOSKeyRead */
  332.  
  333. #else
  334.  
  335. boolean Console_fgets(char *buff, int buflen, char *prompt)
  336. {
  337.  
  338.    if (bflag[F_DOSKEY] )
  339.    {
  340.      printmsg(0,"DOSKEY support not available, option disabled");
  341.      bflag[F_DOSKEY] = FALSE;
  342.    }
  343.  
  344.    fputs(prompt, stdout);
  345.  
  346.    return (fgets(buff, buflen, stdin) != nil(char)) ? TRUE : FALSE;
  347.  
  348. } /*Console_fgets*/
  349.  
  350. #endif
  351.  
  352.  
  353. /*
  354.    L _ i n v o k e _ p a g e r
  355.  
  356.    Invoke the user's pager to view a text file
  357. */
  358.  
  359. int L_invoke_pager(const char *pcmd, const char *filename)
  360. {
  361.    char command[FILENAME_MAX*2 + 1];
  362.    char tempname[FILENAME_MAX];                          /* ahd   */
  363.    int  column = 0;                                      /* ahd   */
  364.  
  365.    if (pcmd == nil(char)) {
  366.       printf("L_invoke_pager: No pager specified.\n");
  367.       return 1;
  368.    }
  369.  
  370.    strcpy(tempname,filename);                            /* ahd   */
  371.  
  372.    while (tempname[column] != '\0') {                    /* ahd   */
  373.       if (tempname[column] ==  '/')                      /* ahd   */
  374.          tempname[column] = '\\';                        /* ahd   */
  375.       column += 1;                                       /* ahd   */
  376.   }                                                      /* ahd   */
  377.  
  378.    sprintf(command, pcmd, tempname);
  379.    if (system(command) != 0) {
  380.       printf("L_invoke_pager: system(\"%s\") failed.\n", command);
  381.       return 2;
  382.    }
  383.  
  384.    return 0;
  385.  
  386. } /*L_invoke_pager*/
  387.  
  388. /*
  389.       C l e a r
  390.  
  391.       Clear the screen
  392.  */
  393. void ClearScreen()
  394. {
  395. #ifdef __TURBOC__                                           /* pdm */
  396.       clrscr();                                             /* ahd */
  397. #else                                                       /* pdm */
  398.       fputs("\033[2J", stdout);     /* ANSI Erase screen       ahd */
  399. #endif                                                      /* pdm */
  400. }
  401.